home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / kernel / stdskclk.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  7KB  |  279 lines

  1. #ifdef  CLOCKS
  2. #include "kernel.h"
  3. #if (NR_DRIVES > 0)    /* assume: no hard disk; no controller */
  4. #include <minix/com.h>
  5. #include <sgtty.h>
  6. #include <minix/callnr.h>
  7. #include "proc.h"
  8.  
  9. #include "staddr.h"
  10. #include "stmfp.h"
  11. #include "sthdc.h"
  12. #include "stdma.h"
  13.  
  14. #define TRACE(x)    /* x */
  15. #define XTRACE(x)    x
  16. #define DEBUG(x)    x
  17.  
  18. /*===========================================================================*
  19.  *                do_xbms                       *
  20.  *===========================================================================*/
  21.  
  22. #define XFERSIZE 13
  23. #define IENABLE()    MFP->mf_ierb |= IB_DINT
  24. #define IDISABLE()    MFP->mf_ierb &= ~IB_DINT
  25.  
  26. /* defines for bms 100 */
  27. #define CLK_100    0x7
  28. #define CLK_ADR1    (CLK_100 * 32)
  29. #define CLK_HOLD    0x1
  30. #define CLK_WRITE    0x2
  31. #define CLK_READ    0x4
  32. #define CLK_WREN    0x8
  33. /* defines for bms 200 */
  34. #define SELECT    0x10
  35. #define SCK_EN    0x08
  36. #define SCK_WRITE    0x80
  37. #define CLK_SCSI    0x6
  38. #define CLK_ADR    (CLK_SCSI * 32)
  39.  
  40. PUBLIC int do_xbms(address, count, rw, minor)
  41. phys_bytes     address;
  42. int        count;
  43. int        rw;
  44. int        minor; /* 0= bms100 1=bms200 */
  45. {
  46.  
  47.   register    r, s, wrbit;
  48.   register    index;
  49.   register    char *cp;
  50.   char    lbuf[XFERSIZE];
  51.   long l;
  52.   unsigned short date,time;
  53.  
  54.  
  55.   /*
  56.    * Carry out the transfer. All parameters have been checked and
  57.    * are set up properly.
  58.    *
  59.    * Every single byte written to the hdc will cause an interrupt.
  60.    * Thus disable interrupts while communicating with hdc. Ready test
  61.    * will be done by busy waiting. Only for real hard disk operations
  62.    * interrupts will be enabled.
  63.    */
  64.   TRACE(printf("hd address:0x%X count=%d minor=%d cmd:%s\n",
  65.     address, count, minor, (rw==DISK_READ)?"READ":"WRITE")
  66.   );
  67.   IDISABLE();
  68.  
  69.   dmagrab(WINCHESTER, dmaint);
  70.   if (rw == DISK_READ && minor == DC_RBMS100) {
  71.     DMA->dma_mode = FDC | HDC;
  72.     DMA->dma_data = CLK_ADR1+CLK_HOLD;
  73.     for(r=100;r>0;r--) ; /* pause */
  74.     DMA->dma_mode = FDC | HDC;
  75.     DMA->dma_data = CLK_ADR1+CLK_READ+CLK_HOLD;
  76.     for(index = 0; index<XFERSIZE; index++) {
  77.         DMA->dma_mode = FDC | HDC | A0;
  78.         DMA->dma_data = (index << 4);
  79.         for(r=3;r>0;r--) ; /* pause */
  80.         lbuf[index] =  DMA->dma_data & 0xf;
  81.     }
  82.     DMA->dma_mode = FDC | HDC;
  83.     DMA->dma_data = CLK_ADR1+0;
  84.     DMA->dma_mode = FDC ;
  85.  
  86.     for(index=0,cp=(char*)address; index<count; index++)
  87.         *cp++ = lbuf[index];
  88.     r = 0; /* good return */
  89.  
  90.   } else if (rw == DISK_READ && minor == DC_RBMS200) {
  91.     DMA->dma_mode = FDC | HDC;
  92.     DMA->dma_data = CLK_ADR+SELECT;
  93.     wr1byte(0x20);
  94.  
  95.     for(index = 0; index<7; index++) {
  96.         lbuf[index] =  rd1byte();
  97.     }
  98.     DMA->dma_data = CLK_ADR+0;
  99.     DMA->dma_mode = FDC ;
  100.  
  101.     cp=(char*)address;
  102. /* lbuf format: bcd H L */
  103.     *cp++ = lbuf[0] & 0xf;
  104.     *cp++ = (lbuf[0]  >> 4) & 0xf;
  105.     *cp++ = lbuf[1] & 0xf;
  106.     *cp++ = (lbuf[1]  >> 4) & 0xf;
  107.     *cp++ = lbuf[2] & 0xf;
  108.     *cp++ = (lbuf[2]  >> 4) & 0xf;
  109.     *cp++ = lbuf[3] & 0xf;
  110.     *cp++ = lbuf[4] & 0xf;
  111.     *cp++ = (lbuf[4]  >> 4) & 0xf;
  112.     *cp++ = lbuf[5] & 0xf;
  113.     *cp++ = (lbuf[5]  >> 4) & 0xf;
  114.     *cp++ = lbuf[6] & 0xf;
  115.     *cp++ = (lbuf[6]  >> 4) & 0xf;
  116.     r = 0; /* good return */
  117.  
  118.   } else if (rw == DISK_READ && (minor==DC_RSUPRA || minor==DC_RICD)) { /* supra or icd*/
  119.     if(minor == DC_RSUPRA)
  120.         l = getsupra();
  121.     else
  122.         l = geticd();
  123. printf("Supra/ICD Clock returned\n\tdate(yyyyyyymmmmddddd)=%x time(hhhhhhmmmmmmsssss)=%x\n",
  124. (int)(l>>16),(int)l);
  125.  
  126.  
  127.     if(l == 0) {
  128.         r = EIO; /* failed */
  129.         goto bms_exit;
  130.     }
  131. /*
  132. !date format:
  133. ! 0-4    (1f)    day    1-31
  134. ! 5-8    >>5 (f)    month    1-12
  135. ! 9-15    >>9 (7f) year    0-119  year 0 == 1980
  136. */
  137.         date = l>>16;
  138.         lbuf[0] = (date >> 9) & 0x7f;
  139.         lbuf[1] = (date >> 5) & 0xf;
  140.         lbuf[2] = (date ) & 0x1f;
  141.         lbuf[3] = 0;
  142. /*
  143. !time format:
  144. ! 0-4    (1f)    2sec    0-29
  145. ! 5-10    >>5 (3f) min    0-59
  146. ! 11-15    >>11 (3f) hour    0-59
  147. !
  148. */
  149.         time = l;
  150.         lbuf[4] = (time >> 11) & 0x3f;
  151.         lbuf[5] = (time >> 5) & 0x3f;
  152.         lbuf[6] = (time  & 0x1f) <<1; /* real seconds */
  153.     
  154.         cp=(char*)address;
  155. /* lbuf format: bcd H L */
  156.         *cp++ = lbuf[6] % 10;
  157.         *cp++ = (lbuf[6]  / 10);
  158.         *cp++ = lbuf[5] % 10;
  159.         *cp++ = (lbuf[5]  / 10);
  160.         *cp++ = lbuf[4] % 10;
  161.         *cp++ = (lbuf[4]  / 10);
  162.  
  163.         *cp++ = 0;
  164.     
  165.         *cp++ = lbuf[2] % 10;
  166.         *cp++ = (lbuf[2]  / 10);
  167.         *cp++ = lbuf[1] % 10;
  168.         *cp++ = (lbuf[1]  / 10);
  169.         *cp++ = lbuf[0] % 10;
  170.         *cp++ = (lbuf[0]  / 10);
  171.         r = 0; /* good return */
  172.     
  173.   } else if (rw == DISK_WRITE && minor == DC_WBMS100) {
  174.  
  175.  
  176.     for(index=0,cp=(char*)address; index<count; index++)
  177.         lbuf[index] = *cp++;
  178.     
  179.     DMA->dma_mode = FDC | HDC;
  180.     DMA->dma_data = CLK_ADR1+CLK_WREN+CLK_HOLD;
  181.     for(r=100;r>0;r--) ; /* pause */
  182.     for(index = 0; index<13; index++) {
  183.         DMA->dma_mode = FDC | HDC | A0;
  184.         DMA->dma_data = (index << 4) | (lbuf[index] & 0xf);
  185.         for(r=1;r>0;r--) ; /* pause */
  186.         DMA->dma_mode = FDC | HDC;
  187.         DMA->dma_data = CLK_ADR1+CLK_WREN+CLK_HOLD+CLK_WRITE;
  188.         for(r=3;r>0;r--) ; /* pause */
  189.         DMA->dma_mode = FDC | HDC;
  190.         DMA->dma_data = CLK_ADR1+CLK_WREN+CLK_HOLD;
  191.     }
  192.     DMA->dma_mode = FDC | HDC;
  193.     DMA->dma_data = CLK_ADR1+CLK_HOLD;
  194.     for(r=100;r>0;r--) ; /* pause */
  195.     DMA->dma_mode = FDC | HDC;
  196.     DMA->dma_data = CLK_ADR1+CLK_READ+CLK_HOLD;
  197.  
  198.     for(index = 0; index<13; index++) {
  199.         DMA->dma_mode = FDC | HDC | A0;
  200.         DMA->dma_data = (index << 4);
  201.         for(r=3;r>0;r--) ; /* pause */
  202.         s =  (unsigned char)DMA->dma_data & 0xf;
  203.         if(s != lbuf[index]) { /* fail */
  204.             DMA->dma_mode = FDC | HDC;
  205.             DMA->dma_data = CLK_ADR1+0;
  206.             DMA->dma_mode = FDC ;
  207.             r = EIO; /* bad return */
  208.             goto bms_exit;
  209.         }
  210.     }
  211.     DMA->dma_mode = FDC | HDC;
  212.     DMA->dma_data = CLK_ADR1+0;
  213.     DMA->dma_mode = FDC ;
  214.     r = 0; /* good return */
  215.   } else if (rw == DISK_WRITE && minor == DC_WBMS200) {
  216.     int l;
  217.  
  218.     cp=(char*)address;
  219.     l = *cp++ & 0xf; /* sec-L */
  220.     lbuf[0] = (*cp++ << 4) | l;
  221.     l = *cp++ & 0xf; /* min-L */
  222.     lbuf[1] = (*cp++ << 4) | l;
  223.     l = *cp++ & 0xf; /* hr-L */
  224.     lbuf[2] = (*cp++ << 4) | l;
  225.     lbuf[2] &= 0x7f;    /* strip the 24 hour bit */
  226.     lbuf[3] = *cp++ & 0xf;
  227.     l = *cp++ & 0xf; /* day-L */
  228.     lbuf[4] = (*cp++ << 4) | l;
  229.     l = *cp++ & 0xf; /* mon-L */
  230.     lbuf[5] = (*cp++ << 4) | l;
  231.     l = *cp++ & 0xf; /* yr-L */
  232.     lbuf[6] = (*cp++ << 4) | l;
  233.     
  234.     DMA->dma_mode = FDC | HDC;
  235.     DMA->dma_data = CLK_ADR+SELECT;
  236.     wr1byte(SCK_WRITE+0x31);
  237.     wr1byte(0xb5);
  238.     wr1byte(0);
  239.     DMA->dma_data = CLK_ADR+0;
  240.  
  241.     DMA->dma_mode = FDC | HDC;
  242.     DMA->dma_data = CLK_ADR+SELECT;
  243.     wr1byte(SCK_WRITE+0x20);
  244.     for(index = 0; index<7; index++) {
  245.         wr1byte(lbuf[index]);
  246.     }
  247.     DMA->dma_data = CLK_ADR+0;
  248.  
  249.     DMA->dma_mode = FDC | HDC;
  250.     DMA->dma_data = CLK_ADR+SELECT;
  251.     wr1byte(0x20);
  252.  
  253.     for(index = 0; index<7; index++) {
  254.         if(lbuf[index] !=  rd1byte()) { /* fail */
  255.             DMA->dma_data = CLK_ADR+0;
  256.             DMA->dma_mode = FDC ;
  257.             r = EIO; /* bad return */
  258.             goto bms_exit;
  259.         }
  260.     }
  261.     DMA->dma_data = CLK_ADR+0;
  262.     DMA->dma_mode = FDC ;
  263.     r = 0; /* good return */
  264.   } else if (rw == DISK_WRITE && minor == DC_RSUPRA) {
  265.     r = EINVAL;
  266.   } else {
  267. /* reserve for screen blanker */
  268.     r = EINVAL;
  269.     goto bms_exit;
  270.   }
  271. bms_exit:
  272.   dmafree(WINCHESTER);
  273.     IENABLE();
  274.   
  275.   return(r);
  276. }
  277. #endif
  278. #endif
  279.